package ronin.ai;

import ronin.actor2d.*;
import ronin.util.Telegram;

public class StateMachine {
	
	// whoever owns this FSM
	private Actor2D owner;
	
	// current states of mind (Concious)
	private State currentState, previousState;

	// this is called everytime the FSM is updated (SubConcious)
	private State globalState;
	
	/**
	 *  Good old constructor, it only needs to know who its owner is.
	 */ 
	public StateMachine(Actor2D theOwner)
	{
		// register the owner of this FSM as a global var
		owner = theOwner;
		
		// reset all state tracking vars to NULL
		currentState = null;
		previousState = null;
		globalState = null;
	}
	
	// Set methods used to change states. 
	public void setCurrentState(State s) { currentState = s; }
	public void setGlobalState(State s) { globalState = s; }
	public void setPreviousState(State s) { previousState = s; }
	
	
	
	/**
	 * This function is the workhorse of the whole package. 
	 */
	public void update()
	{
		// update Subconcious and Concious States. 
		if(globalState != null){ 
			System.out.println("FSM: GlobalState.execute about to run.");
			this.globalState.execute(this.owner);
			System.out.println("FSM: GlobalState.execute just ran");
		}
		if(currentState != null) {
			currentState.execute(owner);
		}
	}
	
	/**
	 * Changes this mind to a given State of mind.
	 */
	public void changeState(State newState)
	{
		previousState = currentState;
		
		if(currentState != null) currentState.exit(owner);
		
		currentState = newState;
		
		currentState.enter(owner);
	}
	
	/**
	 * Duh! It reverts to the previous State of mind : ) 
	 */
	public void revertToPrevious()
	{
		changeState(previousState);
	}
	
	/**
	 * Tests whether this brain is using an instance of or the same State as the one sent.
	 */
	public boolean isInState(State state)
	{
		if(state == currentState) {return true;}
		
		return false;
	}
	/**
	 * Returns the Current State of this Actor.
	 */
	public State currentState() {return currentState;}
	
	/**
	 * Returns the Global State of this Actor.
	 */
	public State globalState() {return globalState;}
	
	/**
	 * Attempts to pass message unto the current and global state, returns true if successfull and false
	 * if not.
	 */
	public boolean handleMessage(Telegram message){
		System.out.println("State Machine is Handling a Message");
		if((currentState!=null) && currentState.onMessage(owner, message))
		{
			return true;
		}
		
		if((globalState!=null) && globalState.onMessage(owner, message) )
		{
			System.out.println("Message passed to global state.");
			return true;
		}
		System.out.println("Message Not handled!");
		return false;
	}
}
